import json
import re
from pydantic import BaseModel, ValidationError, Field
from typing import Optional, List, Literal
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate

load_dotenv()

class ReviewModel(BaseModel):
    product_name: str = Field(description="被评论的产品名称")
    sentiment: Literal["positive", "neutral", "negative"] = Field(description="评论的情感倾向")
    summary: str = Field(description="对评论内容的简短总结")
    mentioned_features: List[str] = Field(description="评论中明确提到的产品功能点")


llm = ChatOpenAI(
    base_url=os.getenv('OPENAI_API_BASE'),
    api_key=os.getenv('OPENAI_API_KEY'),
    model=os.getenv('OPENAI_MODEL'),
    temperature=0.1
)

template = """
作为产品评论分析专家，请深度分析以下查询的特征：
        
查询：{query}

错误信息：{error_msg}

请从以下分析：

1. 提取被评论的产品名称；
2. 分析评论的情感倾向，从["positive", "neutral", "negative"]选取一个；
3. 对评论内容进行简短总结不超过200个字；
4. 用概概括性的语言提炼评论中提到的产品功能点。

严格按照以下例子json格式返回JSON格式数据，不要随便新增字段：
例子：
{{
    "product_name": "土鸡蛋",
    "sentiment": "positive",
    "summary": "土鸡蛋是一个非常有营养的食物。",
    "mentioned_features": ["性价比高", "营养丰富"]
}}
"""

prompt = PromptTemplate(
    input_variables=["query", "error_msg"],  # 定义模板中需要的变量
    template=template                   # 提供模板字符串
)


# 调用 LLM 并尝试解析
def extract_review(query: str, max_retries=10) -> ReviewModel:
    error_msg = ""
    attempt = 0
    while True and attempt < max_retries:
        formatted_prompt = prompt.format(query=query, error_msg=error_msg)
        response = llm.invoke(formatted_prompt)
        content = response.content.strip()

        # 清理可能导致 JSON 解析失败的内容
        content_clean = re.sub(r'[\n\r]+', '', content)
        try:
            data = json.loads(content_clean)
            review = ReviewModel.model_validate(data)
            return review
        except (json.JSONDecodeError, ValidationError) as e:
            # 记录错误，下一轮尝试让 LLM 修正
            error_msg += f"上一次解析失败，错误信息：{str(e)}。原始输出：{content}"
            print(f"[yellow]第 {attempt + 1} 次解析失败，尝试让 LLM 修正...[/yellow]")
            attempt += 1

    raise ValueError(f"解析失败，尝试了 {max_retries} 次，仍未得到合法 JSON。")


if __name__ == '__main__':
    product_interview = """
    “小米YU7”是 小米 汽车公司推出的一款中大型纯电 SUV，是继其轿车型号 SU7 之后的第二款车型。

     它定位为“豪华高性能SUV”，兼具科技感、性能与SUV的空间与实用性。

    亮点参数与特点

    车身尺寸方面：长 4,999 mm，宽 1,996 mm， 高约 1,600 mm；轴距 3,000 mm。

    动力与续航：全系采用 800V 高压平台；

    标准版：单电机后驱，约 230 kW，0‑100km/h ≈ 5.8秒。

    Pro 版：双电机四驱，约 365 kW，0‑100km/h ≈ 4.27秒。


    Max 版：双电机四驱，约 508 kW，0‑100km/h ≈ 3.23秒。

    续航数据：标准版 CLTC 约 835 km，Pro 约 770 km，Max 约 760 km。


    售价范围：官方指导价从约人民币 25.35 万元起至约 32.99 万元。


    储物与空间设计：车内布置了多达 36 处收纳位，最大储物容积达 1,970 L（后排座椅放倒后）等多场景优化。

    安全与结构设计：电池包前方配备一根 1500 MPa 防刮底横梁，并应用与 SU7 Ultra 同款“防弹涂层”以提升安全防护。

    市场反响与抢购情况

    上市初期表现非常抢眼：在开启订购后短短 18 小时内即收获约 24 万份订单。

    虽然订单火爆，但也带来了交付周期较长的问题——部分购车用户被告知需等待 56–59 周。
    Reuters

    适合人群与使用场景

    如果你正在寻找一款 兼具性能与科技感的纯电 SUV：YU7 是一个值得考虑的选择。

    对于注重 空间、储物、家庭使用场景 的用户：其大轴距与细致收纳设计是亮点。

    喜欢 驾驶乐趣、更快加速 的用户，Pro / Max 版本的动力表现尤为出色。

    同时，如果你是小米生态系统（手机、智能家居）用户，希望与车辆形成联动，YU7 在“车‑家‑人”生态方面也有布局。

    需要留意的事项

    虽然配置亮眼、价格实惠，但上市初期的 交车等待时间较长，这是一个需要考虑的因素。

    作为新品牌车型，长期的 可靠性和售后服务网络 相对于老牌车企可能仍在成长中。

    虽然续航数据优异，但实际使用中（气候、载重、驾驶习惯）与标准工况会有差异。建议实地试驾并了解充电布局。
    """
    review = extract_review(product_interview)
    print(review)


